/* 
 * File:   algebra.h
 * Author: gustavo
 *
 * Created on June 4, 2011, 11:26 AM
 */

#ifndef ALGEBRA_H
#define	ALGEBRA_H

#include "matrix.h"

#ifdef	__cplusplus
extern "C" {
#endif


	void alg_max(const Matrix * Mat, Matrix ** Max, Matrix ** Ind);
	void alg_min(const Matrix * Mat, Matrix ** Min, Matrix ** Ind);
	
	void alg_append_right(const Matrix * src_left, const Matrix * src_right, Matrix ** dest);
	void alg_transpose(const Matrix * A, Matrix ** T);

	/**
	 * Compute the somatory of the columns
	 * @param A: is a m by n input matrix.
	 * @param S: is a 1 by n somatory matrix. S must to be previously allocated.
	 */
	void alg_sum(const Matrix * A, Matrix ** Sum);

	/**
	 * Compute Add = A + B
	 * @param A: a m by n input matrix.
	 * @param B: a m by n input matrix.
	 * @param Add: the result of A+B. Add is a m by n matrix and have to be previously allocated.
	 */
	void alg_add(const Matrix * A, const Matrix * B, Matrix ** Add);
	/**
	 * Compute Sub = A - B
	 * @param A: a m by n input matrix.
	 * @param B: a m by n input matrix.
	 * @param Add: the result of A-B. Add is a m by n matrix and have to be previously allocated.
	 */
	void alg_sub(const Matrix * A, const Matrix * B, Matrix ** Sub);
	
	void alg_pow(Matrix * A, double pot);

	/**
	 * Compute Mult = A * B
	 * @param A: a m by n input matrix.
	 * @param B: a n by c input matrix.
	 * @param Mult: the result of A * B. Mult is a m by c matrix and have to be previously allocated.
	 */
	void alg_mult(const Matrix * A, const Matrix * B, Matrix ** Mult);

	/**
	 * Compute the upper triangle matrix of A by row elimination.
	 * @param A: a m by n input matrix.
	 * @param U: The Upper Triangle m by n Matrix. It must to be previously allocated.
	 */
	void alg_upper_triangle(const Matrix * A, Matrix ** Upper);

	double alg_determinant(const Matrix * A);

	/**
	 * Compute the lower triangle matrix of A by row elimination.
	 * @param A: a m by n input matrix.
	 * @param L: The Lower Triangle m by n Matrix. It must to be previously allocated.
	 */
	void alg_lower_triangle(const Matrix * A, Matrix ** Lower);

	/**
	 * Compute the LU factorization, diagonal D and the permutations matrix P of the matrix A.
	 *		<pre> A = PLDU </pre>
	 * @param A: input matrix.
	 * @param P: permutations matrix. If P is NULL, the function will not
	 *			 compute this matrix.
	 * @param L: Lower Triangle matrix.
	 * @param D: Diagonal matrix with the pivots. If D is NULL, the function
	 *			 will not compute this matrix.
	 * @param U: Upper Triangle matrix.
	 */
	void alg_LU(const Matrix * A, Matrix ** P, Matrix ** L, Matrix ** D, Matrix ** U);

	/**
	 * Compute the Reduced Row Echelon Form (rref) of matrix A.
	 * @param A: input matrix.
	 * @param R: reduced row echelon form.
	 * @param idp: a flag vector about the linearity of the columns.
	 *		<br>Zero (0) indicates a dependent column.
	 *		<br>One (1) indicates a independent column.
	 * @param rank the rank of the matrix.
	 */
	void alg_rref(const Matrix * A, Matrix ** R, Matrix ** idp, Matrix ** Null, int * rank);

	/**
	 * Compute the null space of M
	 * @param M: input matrix
	 * @param N: null space
	 */
	void alg_null(const Matrix * M, Matrix ** N);


#ifdef	__cplusplus
}
#endif

#endif	/* ALGEBRA_H */

